home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 483 / mkrscsrc / button.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-29  |  11.2 KB  |  429 lines

  1. #include "stdio.h"
  2. #include "gemdefs.h"
  3. #include "obdefs.h"
  4. #include "osbind.h"
  5. #include "mkrsc.h"
  6. #include "globals.h"
  7.  
  8.  
  9. int do_button(mousex,mousey,clicks)
  10.     int mousex,mousey,clicks;
  11. {
  12.     int result, i, parent;
  13.     OBJECT *inwinptr;
  14.     int mx, my, ms, kbd_state, wi_gw1, dummy;
  15.  
  16. /*    check if mouse is over object in left box.  
  17.     If it is start to drag it over to the right hand window.
  18.     Does both maintree and subtree.
  19. */
  20.  
  21.     result = objc_find(onleft,1,2,mousex,mousey);
  22.     if(result > 1)
  23.     {    drag_left(result);
  24.  
  25.     }
  26. /*    If a window is open check to see if mouse was clicked
  27.     over an object in the window.
  28. */
  29.     else
  30.     {    if(thefrontwin)
  31.      {
  32.     /* set a handy pointer to obj tree in window */
  33.  
  34.         inwinptr = thefrontwin->inwindow->objt;
  35.  
  36. /*    if its a menu tree, check to see if its a title
  37.     if its not a title then search the currently
  38.     open dropdown menu box (mbox)
  39. */
  40.  
  41.     if(thefrontwin->inwindow->kind[0] == TMENU)
  42.         { if( (result = objc_find(inwinptr,2,2,mousex,mousey)) == -1)
  43.           if (thefrontwin->inwindow->mbox > 0)
  44.             result = objc_find(inwinptr,thefrontwin->inwindow->mbox,
  45.                                                         2,mousex,mousey);
  46.         }
  47.     else
  48.         result = objc_find(inwinptr,0,10,mousex,mousey);
  49.  
  50.         if(result != -1)
  51.         {    if(inwinptr == thefrontwin->maintree.objt)
  52.  
  53. /*    If it was over an object in the window and if its the icon maintree. */
  54.  
  55.                 hand_maintree(clicks,result);        
  56.             else
  57.             {    /* else it was over a subtree object    */
  58.                 /* control key depressed? */
  59.                 graf_mkstate(&mx,&my,&ms,&kbd_state); 
  60.                 if(kbd_state == 0x4)
  61.                     if( (thefrontwin->inwindow->kind[0] != TMENU)
  62.                         || ( (inwinptr[result].ob_type != G_TITLE)
  63.                                 && result != thefrontwin->inwindow->mbox ) )
  64.                     {    parent = find_parent(inwinptr,result);
  65.                         if(result != -1)
  66.                             result = parent;
  67.                     }
  68.                     thefrontwin->saved = FALSE;
  69.                     hand_subtree(clicks,result,mousex,mousey);    /* in addsub.c */
  70.             }
  71.         }
  72.         else    /* result == -1, deselect all objects and redraw    */
  73.             {    wind_get(0,WF_TOP,&wi_gw1,&dummy,&dummy,&dummy);
  74.                 if(wi_gw1 == thefrontwin->wihandle)
  75.                 {    for(i=0;i<(thefrontwin->inwindow->count + 1);i++)
  76.                     if(inwinptr[i].ob_state & SELECTED)
  77.                         inwinptr[i].ob_state &= ~SELECTED;
  78.                     draw_inwind(thefrontwin,0);    
  79.                 }
  80.             }
  81.      }            /* if(thefrontwin)            */
  82.     }            /* else                        */
  83. }    
  84.  
  85. /*    find_parent() returns the index number of the parent of the
  86.     object 'result' or returns -1
  87. */
  88.  
  89. int find_parent(objptr,result)
  90.     OBJECT *objptr;
  91.     int    result;
  92. {
  93.     int next, tail, current;
  94.  
  95.     current = result;
  96.     next = objptr[result].ob_next;
  97.     if(result == 0 || next < 0 )
  98.         return(-1); /* bail out if this is root node    */
  99.     while (objptr[next].ob_tail != current)
  100.     {    current = next;
  101.         next = objptr[current].ob_next;
  102.         if(next < 0)
  103.             return(-1); /* bail out if you get lost.. can't happen    */
  104.     }
  105.     return(next);
  106. }
  107.  
  108.  
  109. hand_maintree(clicks,result)
  110.     int clicks, result;
  111. {
  112.     int i;
  113.     OBJECT    *inwinptr;
  114.     int mx, my, mstate, kbdstate;
  115.     objtreeptr    tempmain;
  116.  
  117.             inwinptr = thefrontwin->inwindow->objt;
  118.  
  119.             if(clicks == 2) 
  120.             {
  121.                 dbl_click(result);
  122.             }
  123.             else if (result > 0)        /*  clicks = 1   */
  124.             {
  125.  
  126.     /* making icons radio buttons does not seem to work so I have to
  127.         deselect and redraw the other icons myself
  128.     */
  129.             for(i=1;i<(thefrontwin->inwindow->count + 1);i++)
  130.                 if( (inwinptr[i].ob_state & SELECTED) && (result != i) )
  131.                     inwinptr[i].ob_state &= ~SELECTED;
  132.     
  133.     /* toggle state of the selected icon and redraw tree    */
  134.  
  135.                 inwinptr[result].ob_state ^= SELECTED;
  136.  
  137.     /* check if the mouse button and left-shift are being held down    */
  138.  
  139.         graf_mkstate(&mx, &my, &mstate, &kbdstate);
  140.         if(mstate == 1 && kbdstate == 0x2)
  141.             {     if(tempmain = copy_tree(1));
  142.                 {    if(tempm)
  143.                         {    free(tempm->treelink[0]);
  144.                             free(tempm);
  145.                         }
  146.                         tempm = tempmain;
  147.                         paste_tree(tempm);
  148.                         return;
  149.                 }
  150.             }
  151.  
  152.                 draw_inwind(thefrontwin,0);
  153.  
  154.             }
  155.  
  156. }
  157.  
  158.  
  159. /*     dragging icons from onleft tree to inwindow tree.
  160.     objptr1 is the onleft objptr, index is the object
  161.     selected.
  162. */        
  163.  
  164. drag_left(index)
  165.     int index;
  166. {
  167.     int result, button;
  168.     int sw, sh, sx, sy, bw, bh, bx, by;
  169.     int xoff, yoff;
  170.     int finalx,finaly, new_parent;
  171.     OBJECT *objptr2;
  172.     OBJECT *iconptr;
  173.  
  174.     objc_offset(onleft, index, &xoff, &yoff); /* need xoff yoff for dragbox */
  175.     iconptr = &onleft[index];
  176.  
  177.     sx = xoff;    /* size of box to drag  */
  178.     sy = yoff;
  179.     sw = iconptr->ob_width;
  180.     sh = iconptr->ob_height;
  181.  
  182.     set_clip(xdesk,ydesk,wdesk,hdesk); /* set_clip to desktop */
  183.  
  184.     bx = xdesk; /* sets limits to where you can drag box   */
  185.     by = ydesk;
  186.     bw = wdesk;
  187.     bh = hdesk;
  188.  
  189.         graf_dragbox(sw,sh,sx,sy,bx,by,bw,bh,&finalx,&finaly);
  190.     
  191.     if(thefrontwin)
  192.     {    thefrontwin->saved = FALSE;
  193.         objptr2 = thefrontwin->inwindow->objt;
  194.  
  195. /*    objptr2 points to the active object tree in the window    */
  196.  
  197. /*     new_parent is the index number of the object in the window over which
  198.     the icon has been moved.  'index' is the index number of the icon
  199.     which was moved from the lefthand object tree.
  200. */
  201.         result = objc_find(objptr2,0,10,finalx,finaly);
  202.         if(result != -1)
  203.         {        if(thefrontwin->inwindow == &thefrontwin->maintree)
  204.             /* moving icons to maintree        */
  205.                     add_lefticon(iconptr,index,0);
  206.                 else
  207.             /* moving objects to subtree        */
  208.                 {    new_parent = good_parent(objptr2,finalx,finaly,sw,sh,-2);
  209.                     if(new_parent != -1)
  210.                         add_tosub(iconptr,new_parent,index,finalx,finaly);
  211.                 }
  212.         }
  213.     }
  214. }
  215.  
  216. /*
  217.     You now want to move the icon (object) from the left hand menu pointed
  218.     to by iconptr to the tree structure inwindow.  It must be added to the
  219.     array of objects in inwindow->objt[], and count incremented.  Then you
  220.     must link it to the other objects in the array with objc_add().  You 
  221.     link it to the parent object pointed to by the index number 
  222.     'nindex'.  'oindex' is the index number of the icon in the onleft
  223.     box (tree).  Since this is the maintree of menu and dialog icons
  224.     nindex should always be 0, the box that the window opens with.
  225.     'rflag' = 1 allows this function to be also used for retrieving old
  226.     resource files.  See retrv.c 
  227. */    
  228.  
  229. int add_lefticon(iconptr,oindex, rflag)
  230.     OBJECT        *iconptr;
  231.     int            oindex, rflag;
  232. {
  233.     int result, num, i, nindex;
  234.     int cx,cy,cw,ch;
  235.     OBJECT *objptr2;
  236.     windowptr thewin;
  237.     objtreeptr thetree;
  238.     ICONBLK *ibptr;
  239.     char newname[30];
  240.     
  241.     nindex = 0;
  242.  
  243.     thewin = thefrontwin;
  244.  
  245. /*    copy the icon into the maintree array.     */
  246.  
  247.     thewin->inwindow->objt[++thewin->inwindow->count] = *iconptr;
  248.  
  249.     num = thewin->inwindow->count;
  250.  
  251. /* copy the icon type (menu, dialog or unknown) into 'kind'    */
  252.  
  253.     thewin->inwindow->kind[num] = oindex;
  254.  
  255. /* set up a handy ptr */
  256.     objptr2 = &thewin->inwindow->objt[num];
  257.  
  258. /* clear the pointers for the new object  */
  259.  
  260.     objptr2->ob_next = -1;
  261.     objptr2->ob_head = -1;
  262.     objptr2->ob_tail = -1;
  263.  
  264. /* set its position */
  265.  
  266.     objptr2->ob_x = 20 + ((num-1)%8)*50;
  267.     objptr2->ob_y = 20 + ((num-1)/8)*35;
  268.     
  269. /* make it a last object  */
  270.  
  271.     objptr2->ob_flags |= LASTOB;
  272.  
  273. /* allocate a linked objtree structure for the icon and initialize    */
  274.  
  275.     thetree      = (objtreeptr) malloc(sizeof(objtree));
  276.  
  277.     thetree->count = 0;
  278.     thetree->mbox = 0;
  279.     for(i=0;i<MAXONUM;i++)
  280.     {    thetree->treelink[i] = NULL;
  281.         thetree->kind[i] = 0;
  282.         thetree->name[i][0] = NULL;
  283.         thetree->strings[i][0] = NULL;
  284.         thetree->template[i][0] = NULL;
  285.         thetree->template[i][0] = NULL;
  286.     }
  287.  
  288. /*    set up a flag to later identify the tree as a menu or dialog    */
  289.     thetree->kind[0] = oindex;
  290.  
  291. /*  put addr of linked objtree structure into maintree pointer array  */
  292.     thewin->inwindow->treelink[num] = thetree;
  293.  
  294. /* dup the icon's ICONBLK to the maintree array of ICONBLKs    */
  295.  
  296.     thewin->inwindow->icblk[num] = *((ICONBLK *)(onleft[oindex].ob_spec));
  297.  
  298. /*    Give the linked objtree a starting dialog box or menu bar.
  299.     The value of 17 for the total objects in the dummy menu tree
  300.     may change if the tree is rebuilt.  The number 17, or its 
  301.     relacement should be the total number of objects in the dummy
  302.     menu tree.  Since there are some objects that may have been erased,
  303.     it is the maximum index number into the tree for a object used by
  304.     tree.  (copying 20 objects to be sure but setting count = 16).
  305. */
  306.     if(!(rflag))
  307.     {
  308.     if(oindex == TMENU)
  309.     {    bcopy((char *)dummnu,(char *)thetree->objt,(20*sizeof(OBJECT)));
  310.         thetree->count += 16;  /* 17 objects 0 to 16  */;
  311.         thetree->objt[thetree->count].ob_flags |= LASTOB;
  312.     for(i=0;i<17;i++)
  313.     switch (thetree->objt[i].ob_type)
  314.         {    case G_BUTTON    :
  315.             case G_STRING    :
  316.             case G_TITLE    :
  317.             strcpy(thetree->strings[i],thetree->objt[i].ob_spec);
  318.             thetree->objt[i].ob_spec = thetree->strings[i];
  319.             break;
  320.         }
  321.     }
  322.     else
  323.     {    thetree->objt[0] = *mtbox1;
  324.         thetree->objt[thetree->count].ob_flags |= LASTOB;
  325.     }
  326.     }
  327. /* get its new name, put into maintree name array */
  328.  
  329.     sprintf(thewin->inwindow->name[num],"TREE%03d",++iconum);
  330.     
  331. /* point ob_spec of new icon object to its new ICONBLK structure  */
  332.  
  333.     (ICONBLK *)thewin->inwindow->objt[num].ob_spec =
  334.                                  &thewin->inwindow->icblk[num];
  335.     
  336. /*  and point ICONBLK ptext to 'name' in maintree struct */
  337.  
  338.     thewin->inwindow->icblk[num].ib_ptext = thewin->inwindow->name[num];
  339.  
  340. /* point the tedinfo of the tree namer dialog to newname*/
  341.     if(!(rflag))
  342.     {
  343.         strcpy(newname,thewin->inwindow->name[num]);
  344.     ((TEDINFO *)newtree[NTEDIT].ob_spec)->te_ptext = newname;
  345.     
  346.     result = do_dialog(newtree,NTEDIT);    /* newtree is object from RSC  */
  347.     newtree[NTOK].ob_state = NORMAL;
  348.     newtree[NTCANCEL].ob_state = NORMAL;
  349.  
  350.     if (result == NTCANCEL)
  351.         {    thewin->inwindow->count--;
  352.             free(thetree);
  353.             return;
  354.         }
  355.     if(  (strcmp(newname,thewin->inwindow->name[num]) == 0)
  356.          || (check_name(newname) == 1) )
  357.             strcpy(thewin->inwindow->name[num],newname);
  358.         
  359.     }
  360. /* link the new object into its parent   */
  361.  
  362.     result = objc_add(thewin->inwindow->objt,nindex,num);
  363.     
  364. /* reset the LASTOB for the previous object in tree  */
  365.  
  366.     thewin->inwindow->objt[num-1].ob_flags &= ~LASTOB;
  367.     draw_inwind(thefrontwin,0);
  368.     
  369. }
  370.         
  371. /*    dbl_click() handles icons that have been dbl clicked.  For the root
  372.     objtree, this means drawing the appropriate linked subtree.
  373.     'index' is the number of the object in the 'inwindow' tree.
  374. */
  375.  
  376. int dbl_click(index)
  377.     int index;
  378. {
  379.     OBJECT    *subtrptr;
  380.     objtreeptr    themtree, thesubtree;
  381.     int cx,cy,cw,ch;
  382.  
  383.     if(index == 0)
  384.         return;
  385.  
  386.     cx = thefrontwin->work.g_x;
  387.     cy = thefrontwin->work.g_y;
  388.     cw = thefrontwin->work.g_w;
  389.     ch = thefrontwin->work.g_h;
  390.  
  391.     switch (thefrontwin->inwindow->kind[index])
  392.     {
  393.         case TMENU    :    draw_obj(mnuicont);
  394.                         break;
  395.         case TDIALOG :
  396.         case TUNKNOWN:    draw_obj(obicont);
  397.                         break;
  398.         case 0        :    break;
  399. /*     only maintree icons have kind set ....  this is a lie!
  400.     kind[0] of the subtree is also set to the same value as
  401.     kind[i] of the maintree icon 'i'.  But kind[0] of the maintree
  402.     is always 0.  The icon objects start at 1.
  403. */
  404.     }
  405.  
  406.  
  407.     themtree = thefrontwin->inwindow;
  408.     themtree->mbox = 0;
  409.  
  410.     thesubtree = themtree->treelink[index];
  411.     thefrontwin->inwindow = thesubtree;
  412.  
  413.     /* handy pointer */
  414.  
  415.     subtrptr = thesubtree->objt;
  416.  
  417.     /* put into window */
  418.  
  419.     subtrptr->ob_x = cx;
  420.     subtrptr->ob_y = cy;
  421.     set_clip(cx,cy,cw,ch);
  422.     whiterect(thefrontwin);    
  423.     if(thefrontwin->maintree.kind[index] == TMENU)
  424.         objc_draw(subtrptr,1,2,cx,cy,cw,ch);
  425.     else
  426.         objc_draw(subtrptr,0,10,cx,cy,cw,ch);
  427. }
  428.  
  429.